/**Trigger Name: NMROORAsgroupmemberAlign
 * Author: Accenture
 * Requirement/Project Name: NMR and OOR
 * Requirement Description: Class for Alignment of OOR and NMR users in Assignment group basing on their Hire date
 */
Public Class NMROORAsgroupmemberAlign{
    Public static List<Assignment_Groups__c> AgList = new List<Assignment_Groups__c>();//Store the Assignment group members 
    Public Static Id nmrasgGroupRecordTypeId = RecordTypeHelper.GetRecordTypeID('Assignment_Group_Name__c','NMR Assignment Group');
    Public static ID leadRecordTypeId = RecordTypeHelper.GetRecordTypeID('Lead','NMR Lead');
    //Method for alignment of assignment group members
    Public static void alignGrpMember( Set<Id> updatedIds,Set<Id> AssignGrpList,boolean isInsert,boolean isUpdate,Map<id,Assignment_Groups__c> oldAGmemberMap,List<Assignment_Groups__c> UpdatedList){
            Map<Id,List<Assignment_Groups__c>> grpmap= New Map<Id,List<Assignment_Groups__c>>();
            AgList = getGrpmember(updatedIds,AssignGrpList);
            DateTime ownerDateTime;
            
             for(Assignment_Groups__c Member:AgList){              
                    if(grpmap.containsKey(Member.Group_Name__c)){
                        grpmap.get(Member.Group_Name__c).add(Member); 
                    }
                    else{     
                    grpmap.put(Member.Group_Name__c,new List<Assignment_Groups__c>{Member});
                    }     
             } 
             for(Assignment_Groups__c ag :UpdatedList){
                  if(isInsert || (ag.Active__c != oldAGmemberMap.get(ag.id).Active__c && ag.Active__c == 'True') || (ag.User_Active__c == 'True' && ag.User_Active__c != oldAGmemberMap.get(ag.id).User_Active__c)){
                   Decimal oldestMilliseconds;
                   DateTime oldestDateTimeVal ;
                   DateTime newDateTimeVal ;
                   ag.Last_Assignment__c=DateTime.Now();
                   ag.Millisecond__c=200;
                   double lastvalue = 250;
                  if(grpmap.get(ag.Group_Name__c) != NULL){  
                   for (Assignment_Groups__c aguser : grpmap.get(ag.Group_Name__c))
                       {
                        if(aguser.User__c != ag.User__c){
                        //lastvalue = aguser
                        integer count = 0;
                        if(aguser.Last_Assignment__c!=null && aguser.Millisecond__c!=null && ag.OOR_Hire_Date__c>=aguser.OOR_Hire_Date__c)  
                            {
                             count = count + 1;
                             oldestDateTimeVal=aguser.Last_Assignment__c;
                             oldestMilliseconds=aguser.Millisecond__c;
                             If(count > 1){
                                 ag.Last_Assignment__c=newDateTimeVal;
                                 ag.Millisecond__c = (oldestMilliseconds+lastvalue)/2 ;
                             }
                             else{
                                 ag.Last_Assignment__c=DateTime.Now();
                                 ag.Millisecond__c = (oldestMilliseconds+lastvalue)/2;
                             }
                             
                             
                             break;
                            }  
                            else if(grpmap.get(ag.Group_Name__c).size()>1 && aguser.Millisecond__c != null){
                            lastvalue = aguser.Millisecond__c;
                            newDateTimeVal = aguser.Last_Assignment__c;
                            ag.Millisecond__c = aguser.Millisecond__c - 100;
                            
                            }
                            else If(grpmap.get(ag.Group_Name__c).size()==1 && aguser.Millisecond__c != null){
                                ag.Millisecond__c = aguser.Millisecond__c - 100;   
                                ag.Last_Assignment__c =  aguser.Last_Assignment__c;
                            }
                            else{
                               ag.Millisecond__c =  ag.Millisecond__c - 100;
                               
                            }
                             
                          
                         }  
                         else{
                             ag.User__c.addError('There exists an assignment group member with the same user');
                         }            
                   }
                       
                }
                else{
                    ag.Last_Assignment__c=DateTime.Now();
                    ag.Millisecond__c=200;
                }
                }
             }  
    }
    Public static List<Assignment_Groups__c> getGrpmember( Set<Id> updatedIds,Set<Id> AssignGrpList){
        List<Assignment_Groups__c> AgListNMR = new List<Assignment_Groups__c>();
                                        AgListNMR =[Select Id,Last_Assignment__c,Millisecond__c,OOR_Hire_Date__c,
                                               User__r.Name,User__r.SFA_Office__c,Group_Name__r.Type__c,Group_Name__r.Name,User_Active__c 
                                               from Assignment_Groups__c where 
                                               Group_Name__c IN: AssignGrpList AND (Group_Name__r.Type__c =: 'Lead' OR Group_Name__r.Type__c =: 'NMR - Lead')
                                               AND User_Active__c = 'True' AND Active__c = 'True' AND Id NOT IN: UpdatedIds
                                            Order by OOR_Hire_Date__c DESC];  
                             
                             return AgListNMR;      
    }
    Public static List<Assignment_Groups__c> getGrpmemberOOR( Set<Id> updatedIds,Set<Id> AssignGrpList){
        List<Assignment_Groups__c> AgListOOR = new List<Assignment_Groups__c>();
                                        AgListOOR =[Select Id,Last_Assignment__c,Millisecond__c,OOR_Hire_Date__c,
                                               User__r.Name,User__r.SFA_Office__c,Group_Name__r.Type__c,Group_Name__r.Name,User_Active__c 
                                               from Assignment_Groups__c where 
                                               Group_Name__c IN: AssignGrpList AND User__r.SFA_Office__c != NULL 
                                               AND User_Active__c = 'True' AND Active__c = 'True' AND Id NOT IN: UpdatedIds
                                            Order by OOR_Hire_Date__c DESC];  
                              return AgListOOR;      
    }
    @isTest(SeeAllData=True)    
    static void nmrAssignmentTest(){ 
    List<Assignment_Groups__c> nmrGrp = new List<Assignment_Groups__c>();
    Set<Id> grpId = new Set<Id>();
    List<Assignment_Group_Name__c > newAsGroup = new List<Assignment_Group_Name__c>();
    List<lead> listLead = new List<Lead>();
    List<User> userList = new List<User>();
    
        Assignment_Group_Name__c nmrGroup = new Assignment_Group_Name__c();
        nmrGroup.Name = 'NMR Test Group';
        nmrGroup.Round_Robin__c = True;
        nmrGroup.Type__c = 'NMR - Lead';
        nmrGroup.RecordTypeId = nmrasgGroupRecordTypeId;
        newAsGroup.add(nmrGroup) ;
                
        Assignment_Group_Name__c nmrGroup1 = new Assignment_Group_Name__c();        
        nmrGroup1.Name = 'NMR Test1 Group';
        nmrGroup1.Round_Robin__c = True;
        nmrGroup1.Type__c = 'NMR - Lead';
        nmrGroup1.RecordTypeId = nmrasgGroupRecordTypeId;
        newAsGroup.add(nmrGroup1);
                
        insert newAsGroup;      
        
        Assignment_Groups__c nmrGroupMemb = new Assignment_Groups__c();
        profile profid = [Select Id from profile q where profile.Name ='NMR Sales']; 
        User u1 = new User(alias = 'Opt21', email='sysadminOpty21@accenture.com',timezonesidkey='America/Los_Angeles',emailencodingkey='UTF-8', lastname='Test Opty 21', languagelocalekey='en_US',localesidkey='en_US', profileid = profid.id, username='testOppty21@testorg.com',SFA_Office__c='NYC',IsActive = True,css_office_name__c = 'NYC', OOR_Hire_Date__c = Date.Today() );              
        userList.add(u1);
        User u2 = new User(alias = 'Opt22', email='sysadminOpty22@accenture.com',timezonesidkey='America/Los_Angeles',emailencodingkey='UTF-8', lastname='Test Opty 21', languagelocalekey='en_US',localesidkey='en_US', profileid = profid.id, username='testOppty22@testorg.com',SFA_Office__c='NYC',IsActive = True,css_office_name__c = 'NYC', OOR_Hire_Date__c = (Date.Today()-1) );              
        userList.add(u2);
        User u3 = new User(alias = 'Opt23', email='sysadminOpty23@accenture.com',timezonesidkey='America/Los_Angeles',emailencodingkey='UTF-8', lastname='Test Opty 23', languagelocalekey='en_US',localesidkey='en_US', profileid = profid.id, username='testOppty23@testorg.com',SFA_Office__c='NYC',IsActive = True,css_office_name__c = 'NYC', OOR_Hire_Date__c = (Date.Today()-1) );              
        userList.add(u3); 
        insert userList;
        
        Assignment_Groups__c nmrAsgGroup = new Assignment_Groups__c();
        nmrAsgGroup.User__c = u1.Id;
        nmrAsgGroup.Active__c = 'False';
        nmrAsgGroup.Group_Name__c = nmrGroup.id;
        nmrAsgGroup.Manager__c = u3.Id;  
        nmrGrp.add(nmrAsgGroup);
        grpId.add(nmrAsgGroup.Id); 
        Assignment_Groups__c nmrAsgGroup1 = new Assignment_Groups__c();
        nmrAsgGroup1.User__c = u2.Id;
        nmrAsgGroup1.Active__c = 'True';
        nmrAsgGroup1.Group_Name__c = nmrGroup.id;
        nmrAsgGroup1.Manager__c = u3.Id;  
        nmrGrp.add(nmrAsgGroup1);
        
        grpId.add(nmrAsgGroup1.Id);
        Assignment_Groups__c nmrAsgGroup11 = new Assignment_Groups__c();
        nmrAsgGroup11.User__c = u1.Id;
        nmrAsgGroup11.Active__c = 'True';
        nmrAsgGroup11.Group_Name__c = nmrGroup1.id;
        nmrAsgGroup11.Manager__c = u3.Id;  
        nmrGrp.add(nmrAsgGroup11);
        
        insert nmrGrp;
        nmrAsgGroup.Active__c ='True';
        update nmrAsgGroup;
        
        Assignment_Groups__c nmrAsgGroup12 = new Assignment_Groups__c();
        nmrAsgGroup12.User__c = u1.Id;
        nmrAsgGroup12.Active__c = 'True';
        nmrAsgGroup12.Group_Name__c = nmrGroup.id;
        nmrAsgGroup12.Manager__c = u3.Id;  
        nmrGrp.add(nmrAsgGroup12);
        
        Channel_and_Office_Assignment__c newCOA = new Channel_and_Office_Assignment__c();
        newCOA.Lead_Source__c = 'AdStore';
        newCOA.Lead_Type__c = 'Inquiry';
        newCOA.Zip_Code__c = '56067';
        newCOA.Active__c = True;
        newCOA.Assignment_Group__c = nmrGroup.Id;
        insert newCOA;
        
        Lead newLead = new Lead();
        newLead.FirstName = 'USS Eisenhower';
        newLead.LastName = 'USS Enterprise';
        newLead.Company = 'Stark Enterprise';
        newLead.RecordTypeId = leadRecordTypeId ;
        newLead.LeadSource = 'AdStore';
        newLead.Lead_Type__c = 'Inquiry';
        newlead.PostalCode = '56067';
        listLead.add(newLead);
        
        Lead newLead1 = new Lead();
        newLead1.FirstName = 'USS Eisenhower1';
        newLead1.LastName = 'USS Enterprise1';
        newLead1.Company = 'Stark Enterprise1';
        newLead1.RecordTypeId = leadRecordTypeId ;
        newLead1.LeadSource = 'AdStore';
        newLead1.Lead_Type__c = 'Inquiry';
        newlead1.PostalCode = '56067';
        listLead.add(newLead1);
        insert listLead;
        
        }
    
}